//
//  OSSRecyclingImageUploader.m
//  TaoTuo
//
//  Created by LG on 2020/9/22.
//  Copyright © 2020 刘广. All rights reserved.
//

#import "OSSRecyclingImageUploader.h"
#import <AliyunOSSiOS/OSSService.h>
//需要的一些基本信息
static NSString *const AccessKey = @"LTAIURHPgXg7Ad9y";
static NSString *const SecretKey = @"mxciIzUaIf2Nhjv7OUSWNbLjyhZ4xP";
static NSString *const BucketName = @"taotuo";
static NSString *const AliYunHost = @"http://oss-cn-hangzhou.aliyuncs.com";
static NSString *const kTempFolder = @"ios_taotuo_recycling_image_folder";

@interface OSSRecyclingImageUploader ()

@property (nonatomic, strong) OSSClient *client;

@end

@implementation OSSRecyclingImageUploader

+ (instancetype)sharedLoader
{
    static OSSRecyclingImageUploader *loader = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        loader = [[self alloc] init];
    });
    return loader;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        //        id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:AccessKey secretKey:SecretKey];
        // 自签名模式
        id<OSSCredentialProvider> credential =  [[OSSCustomSignerCredentialProvider alloc] initWithImplementedSigner:^NSString * _Nullable(NSString * _Nonnull contentToSign, NSError * _Nullable __autoreleasing * _Nullable error) {
            NSString *signature = [OSSUtil calBase64Sha1WithData:contentToSign withSecret:SecretKey];
            if (signature != nil) {
                *error = nil;
            } else {
                *error = [NSError errorWithDomain:kBaseURL code:-601 userInfo:@{@"error" : @"oss自签名错误"}];
                return nil;
            }
            return [NSString stringWithFormat:@"OSS %@:%@", AccessKey, signature];
        }];
        
        OSSClientConfiguration * conf = [OSSClientConfiguration new];
        conf.maxRetryCount = 3; // 网络请求遇到异常失败后的重试次数
        conf.timeoutIntervalForRequest = 30; // 网络请求的超时时间
        conf.timeoutIntervalForResource = 1 * 60 * 60; // 允许资源传输的最长时间
        
        self.client = [[OSSClient alloc] initWithEndpoint:AliYunHost credentialProvider:credential clientConfiguration:conf];
    }
    return self;
}

- (void)asyncUploadImage:(UIImage *)image complete:(void(^)(NSArray<NSString *> *names,UploadImageState state))complete
{
    [self uploadImages:@[image] isAsync:YES complete:complete];
}

- (void)syncUploadImage:(UIImage *)image complete:(void(^)(NSArray<NSString *> *names,UploadImageState state))complete
{
    [self uploadImages:@[image] isAsync:NO complete:complete];
}

- (void)asyncUploadImages:(NSArray<UIImage *> *)images complete:(void(^)(NSArray<NSString *> *names, UploadImageState state))complete
{
    [self uploadImages:images isAsync:YES complete:complete];
}

- (void)syncUploadImages:(NSArray<UIImage *> *)images complete:(void(^)(NSArray<NSString *> *names, UploadImageState state))complete
{
    [self uploadImages:images isAsync:NO complete:complete];
}


- (void)uploadImages:(NSArray<UIImage *> *)images isAsync:(BOOL)isAsync complete:(void(^)(NSArray<NSString *> *names, UploadImageState state))complete
{
    OSSRecyclingImageUploader *loader = [OSSRecyclingImageUploader sharedLoader];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = images.count;
    
    NSMutableArray *callBackNames = [NSMutableArray array];
    int i = 0;
    for (UIImage *image in images) {
        if (image) {
            NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
                //任务执行
                OSSPutObjectRequest * put = [OSSPutObjectRequest new];
                put.bucketName = BucketName;
                
                //文件路径及名称拼接
                NSString *imageName = [kTempFolder stringByAppendingPathComponent:[[self randomStringWithLength:18] stringByAppendingString:@".jpg"]];
                put.objectKey = imageName;
                put.contentType = @"image/jpeg";
                //添加到数组回传
                NSLog(@"上传图片名=== %@", imageName);
                //                [callBackNames addObject:imageName];
                
                //上传date
                NSData *data = UIImageJPEGRepresentation(image, 0.3);
                put.uploadingData = data;
                // 阻塞直到上传完成
                OSSTask *putTask = [loader.client putObject:put];
                [putTask waitUntilFinished];
                if (!putTask.error) {
                    OSSTask *t = [loader.client presignPublicURLWithBucketName:BucketName withObjectKey:imageName];
                    // 图片路径
                    [callBackNames addObject:t.result];
                    NSLog(@"上传成功! 图片名=== %@, %@", imageName, t.result);
                    
                } else {
                    NSLog(@"上传失败, error: %@" , putTask.error);
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [MBProgressHUD showAutoHideMessage:putTask.error.localizedDescription];
                    });
                }
                if (isAsync) {
                    if (image == images.lastObject) {
                        NSLog(@"上传完成!");
                        if (!putTask.error) {
                            if (complete) {
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    complete([NSArray arrayWithArray:callBackNames] ,UploadImageSuccess);
                                });
                            }
                        }
                        
                    }
                }
            }];
            if (queue.operations.count != 0) {
                [operation addDependency:queue.operations.lastObject];
            }
            [queue addOperation:operation];
        }
        i++;
    }
    if (!isAsync) {
        [queue waitUntilAllOperationsAreFinished];
        NSLog(@"同步");
        if (complete) {
            if (complete) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    complete([NSArray arrayWithArray:callBackNames], UploadImageSuccess);
                });
            }
        }
    }
}

- (void)deleteImageWithPath:(NSString *)path complete:(void (^)(BOOL))complete
{
    OSSDeleteObjectRequest * delete = [OSSDeleteObjectRequest new];
    delete.bucketName = BucketName;
    delete.objectKey = path;
    
    OSSRecyclingImageUploader *loader = [OSSRecyclingImageUploader sharedLoader];
    OSSTask * deleteTask = [loader.client deleteObject:delete];
    [deleteTask continueWithBlock:^id(OSSTask *task) {
        if (!task.error) {
            NSLog(@"删除成功");
            dispatch_async(dispatch_get_main_queue(), ^{
                complete(YES);
            });
        } else {
            NSLog(@"删除失败, error: %@" , deleteTask.error);
            [MBProgressHUD showAutoHideMessage:deleteTask.error.localizedDescription];
            dispatch_async(dispatch_get_main_queue(), ^{
                complete(NO);
            });
        }
        return nil;
    }];
    
    [deleteTask waitUntilFinished];
}


- (void)asyncUploadVideo:(NSData *)data progress:(HBUploadImageManageProgressBlock)progressBlock complete:(void(^)(NSArray<NSString *> *names, UploadImageState state))complete{
    [self uploadVideo:data isAsync:YES progress:progressBlock complete:complete];
}
- (void)syncUploadVideo:(NSData *)data progress:(HBUploadImageManageProgressBlock)progressBlock complete:(void(^)(NSArray<NSString *> *names, UploadImageState state))complete{
    [self uploadVideo:data isAsync:NO progress:progressBlock complete:complete];
}
/// 上传视频
- (void)uploadVideo:(NSData *)data isAsync:(BOOL)isAsync progress:(HBUploadImageManageProgressBlock)progressBlock complete:(void(^)(NSArray<NSString *> *names, UploadImageState state))complete{
    
    // 2
    id<OSSCredentialProvider> credential = [[OSSPlainTextAKSKPairCredentialProvider alloc] initWithPlainTextAccessKey:AccessKey secretKey:SecretKey];
    
    OSSClient *client = [[OSSClient alloc] initWithEndpoint:AliYunHost credentialProvider:credential];
    
    //任务执行
    OSSPutObjectRequest * put = [OSSPutObjectRequest new];
    put.bucketName = BucketName;
    put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
        // 当前上传段长度、当前已经上传总长度、一共需要上传的总长度
        //NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
        if (progressBlock) {
            progressBlock(bytesSent,totalByteSent,totalBytesExpectedToSend);
        }
    };
    NSString *name = [kTempFolder stringByAppendingPathComponent:[[self randomStringWithLength:18] stringByAppendingString:@".MOV"]];
    put.objectKey = name;
    
    
    // 3
    // 传出url
    NSMutableArray *callBackNames = [NSMutableArray array];
//    NSString *imageUrl = [NSString stringWithFormat:@"%@/%@", rootUrl, name];
//    NSLog(@"打印视频URL:%@",imageUrl);
    //添加到数组回传
//    [callBackNames addObject:imageUrl];
    put.uploadingData = data;
    
    
    OSSTask * putTask = [client putObject:put];
    [putTask continueWithBlock:^id(OSSTask *task) {
        
        task = [client presignPublicURLWithBucketName:BucketName withObjectKey:name];
        
        //返回主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            //返回主线程
            if (!task.error) {
                NSLog(@"upload object success!");
                if (complete) {
                    [callBackNames addObject:task.result];
                    complete([NSArray arrayWithArray:callBackNames], UploadImageSuccess);
                }
            } else {
                NSLog(@"upload object failed, error: %@" , putTask.error);
                if (complete) {
                    complete([NSArray arrayWithArray:callBackNames], UploadImageFailed);
                }
            }
        });
        return nil;
    }];
    
    
}




-(NSString *)randomStringWithLength:(NSInteger)len {
    NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
    
    for (NSInteger i = 0; i < len; i++) {
        [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random_uniform([letters length])]];
    }
    return randomString;
}



@end
